﻿namespace AC.ExtendedRenderer.Toolkit
{
    using ComponentFactory.Krypton.Toolkit;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;

    [ToolboxBitmap(typeof(GroupBox))]
    public class KryptonGroupBox : GroupBox
    {
        private Color _bgColor = Color.Gray;
        private BorderMode _borderMode = BorderMode.FullCustom;
        private bool _darkerColors = true;
        private bool _drawBottomLine;
        private bool _drawShadows;
        private System.Windows.Forms.FlatStyle _flatStyle = System.Windows.Forms.FlatStyle.Standard;
        private bool _forceTransparent;
        private bool _paintDefault;
        private IPalette _palette;
        private PaletteRedirect _paletteRedirect;
        private bool _useAlternateForeColor;

        public KryptonGroupBox()
        {
            base.SetStyle(ControlStyles.UserPaint, true);
            base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            base.UpdateStyles();
            if (this._palette != null)
            {
                this._palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
            }
            KryptonManager.GlobalPaletteChanged += new System.EventHandler(this.OnGlobalPaletteChanged);
            this._palette = KryptonManager.CurrentGlobalPalette;
            this._paletteRedirect = new PaletteRedirect(this._palette);
            this.InitColors();
        }

        private void InitColors()
        {
            if (this.BackColor == Color.Transparent)
            {
                this._forceTransparent = true;
            }
            this._bgColor = this._palette.ColorTable.ToolStripGradientMiddle;
            if (this._darkerColors)
            {
                this._bgColor = this._palette.ColorTable.MenuStripGradientEnd;
            }
            if (!this._useAlternateForeColor)
            {
                this.ForeColor = this._palette.ColorTable.StatusStripText;
            }
            else
            {
                this.ForeColor = this._palette.ColorTable.MenuItemText;
            }
            if (this.FlatStyle == System.Windows.Forms.FlatStyle.System)
            {
                this.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
            }
        }

        private void OnGlobalPaletteChanged(object sender, EventArgs e)
        {
            if (this._palette != null)
            {
                this._palette.PalettePaint -= new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
            }
            this._palette = KryptonManager.CurrentGlobalPalette;
            this._paletteRedirect.Target = this._palette;
            if (this._palette != null)
            {
                this._palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(this.OnPalettePaint);
                this.InitColors();
            }
            base.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (this._paintDefault || (this._borderMode == BorderMode.Full))
            {
                base.OnPaint(e);
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            this.InitColors();
            if (this._forceTransparent)
            {
                this.BackColor = Color.Transparent;
                this._bgColor = Color.Transparent;
            }
            if (!this._paintDefault)
            {
                e.Graphics.FillRectangle(new SolidBrush(this._bgColor), e.ClipRectangle);
                Size size = TextRenderer.MeasureText(this.Text, this.Font);
                switch (this._borderMode)
                {
                    case BorderMode.None:
                        TextRenderer.DrawText(e.Graphics, this.Text, this.Font, new Point(6, 0), this.ForeColor);
                        size = TextRenderer.MeasureText(this.Text, this.Font);
                        return;

                    case BorderMode.Header:
                        TextRenderer.DrawText(e.Graphics, this.Text, this.Font, new Point(6, 0), this.ForeColor);
                        size = TextRenderer.MeasureText(this.Text, this.Font);
                        e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripDark), new Point(size.Width + 5, (size.Height / 2) + 1), new Point(base.Width - 3, (size.Height / 2) + 1));
                        if (this._drawShadows)
                        {
                            e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripLight), new Point(size.Width + 6, (size.Height / 2) + 2), new Point(base.Width - 2, (size.Height / 2) + 2));
                        }
                        if (this._drawBottomLine)
                        {
                            e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripDark), new Point(1, base.Height - 3), new Point(base.Width - 3, base.Height - 3));
                            if (this._drawShadows)
                            {
                                e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripLight), new Point(2, (base.Height - 3) + 1), new Point(base.Width - 2, (base.Height - 3) + 1));
                                return;
                            }
                        }
                        return;

                    case BorderMode.FullCustom:
                        TextRenderer.DrawText(e.Graphics, this.Text, this.Font, new Point(6, 0), this.ForeColor);
                        size = TextRenderer.MeasureText(this.Text, this.Font);
                        e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripDark), new Point(size.Width + 6, (size.Height / 2) + 1), new Point(base.Width - 3, (size.Height / 2) + 1));
                        if (this._drawShadows)
                        {
                            e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripLight), new Point(size.Width + 6, (size.Height / 2) + 2), new Point(base.Width - 3, (size.Height / 2) + 2));
                        }
                        e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripDark), new Point(2, base.Height - 3), new Point(base.Width - 3, base.Height - 3));
                        if (this._drawShadows)
                        {
                            e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripLight), new Point(2, (base.Height - 3) - 1), new Point(base.Width - 3, (base.Height - 3) - 1));
                        }
                        e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripDark), new Point(base.Width - 2, (size.Height / 2) + 2), new Point(base.Width - 2, base.Height - 4));
                        if (this._drawShadows)
                        {
                            e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripLight), new Point(base.Width - 3, (size.Height / 2) + 2), new Point(base.Width - 3, base.Height - 4));
                        }
                        e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripDark), new Point(1, (size.Height / 2) + 2), new Point(1, base.Height - 4));
                        if (this._drawShadows)
                        {
                            e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripLight), new Point(2, (size.Height / 2) + 2), new Point(2, base.Height - 4));
                        }
                        e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripDark), new Point(2, (size.Height / 2) + 1), new Point(5, (size.Height / 2) + 1));
                        if (this._drawShadows)
                        {
                            e.Graphics.DrawLine(new Pen(this._palette.ColorTable.GripLight), new Point(3, (size.Height / 2) + 2), new Point(5, (size.Height / 2) + 2));
                        }
                        return;

                    case BorderMode.Full:
                        return;
                }
            }
        }

        private void OnPalettePaint(object sender, PaletteLayoutEventArgs e)
        {
            base.Invalidate();
        }

        [Browsable(true), Category("Appearance-Extended"), DefaultValue("FullCustom")]
        public BorderMode BorderStyle
        {
            get
            {
                return this._borderMode;
            }
            set
            {
                this._borderMode = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true), DefaultValue("true")]
        public bool DarkerColors
        {
            get
            {
                return this._darkerColors;
            }
            set
            {
                this._darkerColors = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true), DefaultValue("false")]
        public bool DrawBottomLine
        {
            get
            {
                return this._drawBottomLine;
            }
            set
            {
                this._drawBottomLine = value;
                base.Invalidate();
            }
        }

        [Browsable(true), Category("Appearance-Extended"), DefaultValue("false")]
        public bool DrawShadows
        {
            get
            {
                return this._drawShadows;
            }
            set
            {
                this._drawShadows = value;
                base.Invalidate();
            }
        }

        public System.Windows.Forms.FlatStyle FlatStyle
        {
            get
            {
                return this._flatStyle;
            }
            set
            {
                this._flatStyle = System.Windows.Forms.FlatStyle.Standard;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), DefaultValue("false"), Browsable(true)]
        public bool ForceTransparent
        {
            get
            {
                return this._forceTransparent;
            }
            set
            {
                this._forceTransparent = value;
                base.Invalidate();
            }
        }

        [Category("Appearance-Extended"), Browsable(true), DefaultValue("false")]
        public bool PaintDefault
        {
            get
            {
                return this._paintDefault;
            }
            set
            {
                this._paintDefault = value;
                base.Invalidate();
            }
        }

        [DefaultValue("false"), Browsable(true), Category("Appearance-Extended")]
        public bool UseAlternateForeColor
        {
            get
            {
                return this._useAlternateForeColor;
            }
            set
            {
                this._useAlternateForeColor = value;
                base.Invalidate();
            }
        }

        public enum BorderMode
        {
            None,
            Header,
            FullCustom,
            Full
        }
    }
}

